#include "cir_queue.h"

/*清零函数*/
void * my_memset(void *source,int dest,int n)
{
    char *c_s=(char *)source;
    while(n--) *c_s++=dest;
    return source;
}


inline void Qdreate_queue(void * const Me)
{
    Cir_queue const * const _Me=(Cir_queue * const)Me;
    
    _Me->c_vptr->delete_queue(Me);
}

inline cbool Qempty(void const * const Me)
{
    Cir_queue const * const _Me=(Cir_queue * const)Me;
    
    return _Me->c_vptr->empty(Me);
}


inline cbool Qfull(void const * const Me)
{
    Cir_queue const * const _Me=(Cir_queue const * const)Me;
    
    return _Me->c_vptr->full(Me);
}

inline cbool Qpop(void * const Me,QUEUE_TYPE *Get)
{
    Cir_queue const * const _Me=(Cir_queue * const)Me;
    
    return _Me->c_vptr->pop(Me,Get);
}

inline cbool Qpush(void * const Me,QUEUE_TYPE value)
{
    Cir_queue const * const _Me=(Cir_queue * const)Me;
    
    return _Me->c_vptr->push(Me,value);    
}

inline cbool Qtail_pop(void * const Me,QUEUE_TYPE *Get)
{
    Cir_queue const * const _Me=(Cir_queue * const)Me;
    
    return _Me->c_vptr->pop(Me,Get);
}

inline cbool Qhead_push(void * const Me,QUEUE_TYPE value)
{
    Cir_queue const * const _Me=(Cir_queue * const)Me;
    
    return _Me->c_vptr->push(Me,value); 
}

inline cbool Qback(void const * const Me,QUEUE_TYPE *Get)
{
    Cir_queue const * const _Me=(Cir_queue * const)Me;
    
    return _Me->c_vptr->back(Me,Get);    
}

inline cbool Qfront(void const * const Me,QUEUE_TYPE *Get)
{
    Cir_queue const * const _Me=(Cir_queue * const)Me;
    
    return _Me->c_vptr->front(Me,Get);    
}

inline int Q_lenth(void const * const Me)
{
    Cir_queue const * const _Me=(Cir_queue * const)Me;
    
    return _Me->c_vptr->lenth(Me);      
}

void Cir__Qcreate_queue(Cir_queue * const Me)
{
    /*清零*/
    my_memset(Me,0,sizeof(Cir_queue));
    /*函数表绑定*/
    static struct Que_vtable  table;
    // table.create_queue=(void (*)(void *))(void(*)(Cir_queue *))Cir__Qcreate_queue;
    table.delete_queue=(void (*)(void *))(void(*)(Cir_queue *))Cir__Qdreate_queue;
    table.empty=(cbool (*)(void const *const ))(cbool(*)(Cir_queue  const* const))Cir__Qempty;
    table.full=(cbool (*)(void const * const ))(cbool(*)(Cir_queue const *const))Cir__Qfull;
    table.pop=(cbool (*)(void *const ,QUEUE_TYPE *Get))(cbool(*)(Cir_queue *const,QUEUE_TYPE *Get))Cir__Qpop;
    table.push=(cbool (*)(void *const,QUEUE_TYPE value))(cbool(*)(Cir_queue *const,QUEUE_TYPE value))Cir__Qpush;
    table.tail_pop=(cbool (*)(void *const,QUEUE_TYPE *Get))(cbool(*)(Cir_queue *const,QUEUE_TYPE *Get))Cir_Qtail_pop;
    table.head_push=(cbool (*)(void *const,QUEUE_TYPE value))(cbool(*)(Cir_queue *const,QUEUE_TYPE value))Cir_Qhead_push;
    table.back=(cbool (*)(void  const* const,QUEUE_TYPE *Get))(cbool(*)(Cir_queue  const*const ,QUEUE_TYPE *Get))Cir__Qback;
    table.front=(cbool (*)(void  const* const,QUEUE_TYPE *Get))(cbool(*)(Cir_queue  const*const ,QUEUE_TYPE *Get))Cir__Qfront;
    table.lenth=(int (*)(void  const* const))(int (*)(Cir_queue  const*const))Cir__Q_lenth;
    Me->c_vptr=&table;

    Me->max_len=QUE_MAX_LEN;
}

void Cir__Qdreate_queue(Cir_queue * const Me)
{
    return ;
}
cbool Cir__Qempty(Cir_queue const * const Me)
{
    if(Me->head==Me->tail) return TRUE;
    else return FALSE;
}
cbool Cir__Qfull(Cir_queue const * const Me)
{
    if(Me->head==(Me->tail+1)%QUE_MAX_LEN) return TRUE;
    else return FALSE;
}

cbool Cir__Qpop(Cir_queue * const Me,QUEUE_TYPE *Get)
{
    if(Cir__Qempty(Me)) return FALSE;
       
    else
    {
        *Get=Me->Queue_Buffer[Me->head];
        Me->head=(Me->head+1)%QUE_MAX_LEN;
        Me->lenth--;
        return TRUE;
    }     

}

cbool Cir__Qpush(Cir_queue * const Me,QUEUE_TYPE value)
{
    if(Cir__Qfull(Me)) return FALSE;
       
    else
    {
        Me->Queue_Buffer[Me->tail]=value;
        Me->tail=(Me->tail+1)%QUE_MAX_LEN;
        Me->lenth++;
        return TRUE;
    }    
}

cbool Cir_Qtail_pop(Cir_queue * const Me,QUEUE_TYPE *Get)
{
    if(Cir__Qempty(Me)) return FALSE;
       
    else
    {
        Me->tail=((Me->tail-1+QUE_MAX_LEN)%QUE_MAX_LEN);
        *Get=Me->Queue_Buffer[(Me->tail)];
        Me->lenth--;
        return TRUE;
    }        
}

cbool Cir_Qhead_push(Cir_queue * const Me,QUEUE_TYPE value)
{
    if(Cir__Qfull(Me)) return FALSE;
       
    else
    {
        Me->head=((Me->head-1+QUE_MAX_LEN)%QUE_MAX_LEN);
        Me->Queue_Buffer[Me->head]=value;
        Me->lenth++;
        return TRUE;
    }      
}

cbool Cir__Qback(Cir_queue const * const Me,QUEUE_TYPE *Get)
{
    if(Cir__Qempty(Me)) return FALSE;
    else
    {
        *Get=Me->Queue_Buffer[(Me->tail-1)%QUE_MAX_LEN];
        return TRUE;
    }

}

cbool Cir__Qfront(Cir_queue const * const Me,QUEUE_TYPE *Get)
{
    if(Cir__Qempty(Me)) return FALSE;
    else
    {
        *Get=Me->Queue_Buffer[Me->head%QUE_MAX_LEN];
        return TRUE;
    }
}

int Cir__Q_lenth(Cir_queue const * const Me)
{
    return Me->lenth;
}
